O’Hara on GitHub


1 Summary

Read in taxonomic traits filled in by taxon experts and cleaned in prior scripts. Combine with coded sensitivity, adaptive capacity, and exposure from stressor-trait sheets to calculate vulnerability.

2 Data

_raw_data/xlsx/master_all_taxa_trait_data.xlsx is the raw workbook prepared by Nathalie Butt from the various submissions of the taxa-group experts. This has been processed and cleaned to _data/spp_traits_valid.csv. See earlier scripts in the process.

trait_stressor_rankings/final_scores_all_stressors_traits.xlsx is a workbook with each sheet indicating sensitivity or adaptive capacity; columns in each sheet indicate stressors, and rows indicate traits.

3 Methods

3.1 Use scored sensitivity traits to stressors against species scored to traits

Set up a function to consistently clean trait values. Trait values in the species trait file are already cleaned and adjusted in many cases to get around mismatches; they are generally lower case, no punctuation except for greater/less than signs.

This function also cleans up category and trait names for consistency. All lower case, punctuation and spaces replaced with underscores. The species trait file is already cleaned in this manner.

clean_traitnames <- function(df, overwrite_clean_col = FALSE) {
  df <- df %>% 
    mutate(category = str_replace_all(category, '[^A-Za-z0-9]+', '_') %>% tolower(),
           category = str_replace_all(category, '^_|_$', ''),
           trait    = str_replace_all(trait, '[^A-Za-z0-9]+', '_') %>% tolower(),
           trait    = str_replace_all(trait, '^_|_$', ''))
  if(!overwrite_clean_col & ('trait_value' %in% names(df))) {
      return(df) ### without overwriting existing trait_value
  }
  if(overwrite_clean_col & ('trait_value' %in% names(df))) {
    x <- readline(prompt = 'Overwriting existing trait_value column? y/n ')
    if(str_detect(x, '^n')) stop('dammit!')
  }
  ### overwrite existing, or add new
  df <- df %>%
    mutate(trait_value = str_replace_all(tolower(trait_value), '[^0-9a-z<>]', ''))
  
  return(df)
}

clean_traitvals <- function(df) {
  x <- df$trait_value
  ### First: remove numeric commas
  y <- str_replace_all(x, '(?<=[0-9]),(?=[0-9])', '') %>%
    ### then: drop all non-alphanumeric and a few key punctuation:
    str_replace_all('[^0-9a-zA-Z<>,;\\-\\.\\(\\)/ ]', '') %>% 
    ### lower case; do it after dropping any weird non-ascii characters:
    tolower() %>% 
    str_trim() %>%
    str_replace_all('n/a', 'na') %>%
    ### convert remaining commas and slashes to semicolons:
    str_replace_all('[,/]', ';') %>%
    ### drop spaces after numbers e.g. 3 mm -> 3mm:
    str_replace_all('(?<=[0-9]) ', '') %>%
    ### drop spaces before or after punctuation (non-alphanumeric):
    str_replace_all(' (?=[^a-z0-9\\(])|(?<=[^a-z0-9\\)]) ', '') %>%
    ### manually fix some valid slashes:
    str_replace_all('nearly sessile;sedentary', 'nearly sessile/sedentary') %>%
    str_replace_all('live birth;egg care', 'live birth/egg care') %>%
    str_replace_all('chitin;caco3mix', 'chitin/caco3 mix') %>%
    str_replace_all('0.5-49mm', '0.5mm-49mm')
    
  df$trait_value <- y
  return(df)
}

assign_rank_scores <- function(x) {
  y <- tolower(as.character(x))
  z <- case_when(!is.na(as.numeric(x)) ~ as.numeric(x),
                 str_detect(y, '^na')  ~ NA_real_,
                 str_detect(y, '^n')   ~ 0.00, ### none, NA, no
                 str_detect(y, '^lo')  ~ 0.33,
                 str_detect(y, '^med') ~ 0.67,
                 str_detect(y, '^hi')  ~ 1.00,
                 str_detect(y, '^y')   ~ 1.00, ### yes
                 TRUE                  ~ NA_real_) ### basically NA
  return(z)
}

Since the species trait file is already cleaned, DO NOT use the clean_traitvals function - it will overwrite the trait_value column.

3.1.1 Check matching

Unmatched traits between sensitivity scoring sheets and species trait sheets:

These traits are in the species-trait scoring sheets but not found in the sensitivity trait scores (should be adaptive capacity/exposure traits only):

navigation_requirements_sound_or_light_or_magnetic, number_of_sites, number_of_sites_incl_terrestrial_wetlands, adult_mobility, planktonic_larval_duration_pld_exposure, age_to_1st_reproduction_generation_time, are_there_sub_populations, can_the_sex_ratio_be_altered_by_a_stressor, fecundity, global_population_size, lifetime_reproductive_opportunities, max_age, parental_investment, post_birth_hatching_parental_dependence, reproductive_strategy, depth_min_max, eoo_range, zone, if_one_few_size, sub_population_dependence_on_particular_sites

These traits are in the trait-sensitivity scoring sheet but not found in the species scoring (need to be scored for species):

navigation_requirements_sound, navigation_requirements_light, navigation_requirements_magnetic

3.1.3 Sensitivity to top three stressors by taxon

3.2 Score general adaptive capacity

General adaptive capacity traits are basically related to the overall population’s resilience in the face of a threat. Large extents of occurrence, large population sizes, presence of multiple subpopulations, and reproductive strategies fall into this category.

3.2.1 Check matching

Unmatched traits between general adaptive capacity scoring sheet and species trait sheets:

Traits in species-trait sheets not in general adcap scores: adult_body_mass_body_size, biomineral, calcium_carbonate_structure_location, calcium_carbonate_structure_stages, communication_requirement_sound, extreme_pressure_wave_sensitive_structures, flight, navigation_requirements_sound_or_light_or_magnetic, respiration_structures, adult_mobility, planktonic_larval_duration_pld_exposure, dissolved_oxygen, ph, salinity, sensitivity_to_wave_energy_physical_forcing, thermal_sensitivity_to_heat_spikes_heat_waves, thermal_sensitivity_to_ocean_warming_max_temps_tolerated, can_the_sex_ratio_be_altered_by_a_stressor, feeding_larva_post_hatching_metamorphosis, depth_min_max, zone, air_sea_interface, dependent_interspecific_interactions, extreme_diet_specialization, light_dependence, terrestrial_and_marine_life_stages, if_one_few_size, within_stage_dependent_habitats_condition, across_stage_dependent_habitats_condition

Traits in general adcap scores but not in spp traits:

  • Median: 6.67
  • Mean: 6.4890888
  • Standard Deviation: 2.262208

3.3 Score specific adaptive capacity

Specific adaptive capacity traits are basically related to an organism’s ability to avoid or mitigate exposure, primarily through movement and larval dispersal.

3.3.1 Check matching

Unmatched traits between specific adaptive capacity scoring sheet and species trait sheets:

Traits in species-trait sheets, not in specific adaptive capacity scores:

adult_body_mass_body_size, biomineral, calcium_carbonate_structure_location, calcium_carbonate_structure_stages, communication_requirement_sound, extreme_pressure_wave_sensitive_structures, flight, navigation_requirements_sound_or_light_or_magnetic, respiration_structures, number_of_sites, number_of_sites_incl_terrestrial_wetlands, dissolved_oxygen, ph, salinity, sensitivity_to_wave_energy_physical_forcing, thermal_sensitivity_to_heat_spikes_heat_waves, thermal_sensitivity_to_ocean_warming_max_temps_tolerated, age_to_1st_reproduction_generation_time, are_there_sub_populations, fecundity, feeding_larva_post_hatching_metamorphosis, global_population_size, lifetime_reproductive_opportunities, max_age, parental_investment, post_birth_hatching_parental_dependence, reproductive_strategy, eoo_range, air_sea_interface, dependent_interspecific_interactions, extreme_diet_specialization, light_dependence, terrestrial_and_marine_life_stages, if_one_few_size, sub_population_dependence_on_particular_sites, within_stage_dependent_habitats_condition, across_stage_dependent_habitats_condition

Traits in specific ad cap scores, not in spp-traits:

3.3.2 specific adaptive capacity by stressor and species group

stressor median mean sd
air_temp 2.340 2.080596 0.9214111
biomass_removal 2.000 2.331776 1.2090186
disease_pathogens 2.000 2.346963 1.2129670
entanglement 2.670 2.866822 1.1298165
eutrophication_nutrient_pollution 2.670 2.773540 1.0860395
habitat_loss_degradation 3.000 3.121495 1.3207275
inorganic_pollution 3.000 3.202979 1.1684356
invasive_species 2.000 2.139019 1.0978218
light_pollution 3.000 2.855911 1.1559954
noise_pollution 3.000 3.054603 1.3111947
oa 3.670 3.889498 1.4347817
oceanographic 2.835 3.039416 1.3094819
organic_pollution 3.000 3.202979 1.1684356
plastic_pollution 3.000 2.552185 1.2225042
poisons_toxins 3.000 3.242687 1.1413274
salinity 3.340 3.543703 1.2411203
sedimentation 2.670 2.612629 1.0881421
slr 1.000 1.452103 0.7976839
storm_disturbance 2.670 2.940561 1.1633742
uv 1.670 1.609474 1.1491012
water_temp 3.330 3.213388 1.3357656
wildlife_strike 1.670 1.914416 1.1767261

3.3.3 Adaptive capacity to top three stressors by taxon

3.4 Assign exposure potential modifier

Exposure potential modifier checks whether the depth and oceanic zones of the stressor match with the depth and oceanic zones of the species. These fall into the “spatial scale” category with the exception of EOO.

3.4.1 These species are not listed as potential exposure to these stressors:

Note: this is exposure potential only, based on overlap between species presence and stressor presence - nothing about sensitivity or actual exposure. Check that these logic out.

4 Combine scores

We will try a calculation for vulnerability \(V\) of species \(i\) to stressor \(j\) that basically looks like this:

\[\text{sensitivity score } S_{i,j} = \mathbf{s}_j^T \mathbf{t}_i\] based on a vector \(\mathbf{s}_j\) of trait-based sensitivity to stressor \(j\), and vector \(\mathbf{t}_i\) of traits of species \(i\);

\[\text{specific adaptive capacity score } K_{i,j} = \mathbf{k}_j^T \mathbf{t}_i\] based on vector \(\mathbf{k}_j\) of trait-based specific adaptive capacity to stressor \(j\); \[\text{general adaptive capacity score } G_{i} = \mathbf{g}^T \mathbf{t}_i\] based on vector \(\mathbf{g}\) of trait-based general adaptive capacity;

\[\text{exposure potential modifier } E_{i,j} = \begin{cases} 1 \text{ when }\mathbf{e}_j^T \mathbf{t}_i > 0\\ 0 \text{ else} \end{cases}\] based on vector \(\mathbf{e}_j\) of trait-based presence of stressor \(j\) (i.e. depth zones and ocean zones in which stressor occurs).

\[\text{vulnerability } V_{i,j} = \frac{S_{i,j} / {S_j}'}{1 + G_i/ {G}' + K_{i,j}/ {K_j}'} \times E_{i,j}\] Each component (\(S_{i,j}, G_i, K_{i,j}\)) is normalized by a reference value (\(S_{j}', G', K_{j}'\) using mean, median, max, etc) for that component for that stressor across all species. Note: median risks referencing to zero for some stressors with few sensitivities (e.g. light pollution); mean risks having a very low reference for the same. Max risks being driven by an outlier, but here the sensitivity scores are generally capped at some low-ish value since there are a finite number of traits that can confer sensitivity. Therefore, we will use max as the reference point. We may wish to consider max possible, which may differ from max observed, in a future iteration?

For species groups with NA in specific adaptive capacity, force to zero (no matching adaptive traits); for species with NA in exposure potential, force to 1 (assume exposure potential).

These results will be saved by species group for now, for future matching to the species level.

4.0.2 Vulnerability to top three stressors by taxon

taxon stressor vuln
cephalopods eutrophication_nutrient_pollution 0.3571670
cephalopods oceanographic 0.3518955
cephalopods oa 0.3338960
corals light_pollution 0.5485537
corals eutrophication_nutrient_pollution 0.4778458
corals salinity 0.4583673
crustacea_arthropods biomass_removal 0.3237831
crustacea_arthropods organic_pollution 0.2637598
crustacea_arthropods inorganic_pollution 0.2619874
echinoderms water_temp 0.4404271
echinoderms eutrophication_nutrient_pollution 0.4341521
echinoderms oceanographic 0.4099282
elasmobranchs biomass_removal 0.3543595
elasmobranchs oceanographic 0.3194125
elasmobranchs poisons_toxins 0.2922977
fish salinity 0.3327372
fish inorganic_pollution 0.3303307
fish oa 0.2978080
marine_mammals biomass_removal 0.6092336
marine_mammals entanglement 0.5813039
marine_mammals wildlife_strike 0.4312690
molluscs inorganic_pollution 0.3567386
molluscs oa 0.3508838
molluscs organic_pollution 0.3493925
plants_algae light_pollution 0.4853934
plants_algae biomass_removal 0.3094275
plants_algae organic_pollution 0.3020574
polychaetes uv 0.3969201
polychaetes habitat_loss_degradation 0.1552287
polychaetes plastic_pollution 0.1367801
reptiles biomass_removal 0.5134315
reptiles invasive_species 0.4834334
reptiles entanglement 0.4576065
seabirds invasive_species 0.4145493
seabirds biomass_removal 0.3843251
seabirds slr 0.3653138
sponges organic_pollution 0.2243921
sponges noise_pollution 0.2162592
sponges oceanographic 0.1848933

5 TO DO

  • fix navigation requirements (light, sound, magnetic) into separate rows where appropriate
    • e.g. cetaceans navigate by sound; birds/turtles/sharks maybe by magnetic; turtles by light?
    • this has to be done on the species trait sheet level.
  • get traits for more species
    • where are the rest of the corals?
    • more fish?
    • extract some values from FishBase and SealifeBase perhaps
    • note these can be gapfilled but more info at spp level = better